#!/usr/bin/env python3.9
# Chris Baird <cjb@brushtail.apana.org.au> did this 201611-202105

UNOIP = "192.168.1.202"
ORGMAXLEN = 64
MAXLEN = 80

import sys, re, socket, time
from PIL import Image, ImageFilter
import colorsys


def coloursort (k):
    # Hamming-distance-esque
    s = 0
    for c in [ ord(k[1]), ord(k[2]), ord(k[3]), ord(k[4]) ]:
        c = c - 48
        if c > 9: c = c - 7
        s = (s << 4) + c

    b = (s & 0x1F) << 3
    g = ((s & 0x7E0) >> 5) << 2
    r = (s >> 11) << 3

    t = max((max(r,g),b))
    mi = min((min(r,g),b))
    md = r+g+b-t-mi
    #return 0
    #return 1024 - abs(1024 - (t*64 + mi*16 + md))
    #return len(k)
    #return - (r*r + g*g + b*b) - (len(k))
    #return - (r*r + g*g + b*b)
    #return 384 - abs(384 - r - g - b)
    #return len(k)*(384 - abs(384 - r - g - b))
    #return 15 - max((max(r,g),b))
    #return -1*(abs(r-g)*abs(r-g) + abs(r-b)*abs(r-b) + abs(g-b)*abs(g-b))
    #return 256 - min(min(r,g), b) + max(max(r,g),b)
    h,s,v = colorsys.rgb_to_hsv (r/255., g/255., b/255.)
    return abs(0.5-s)

def RGB(pixel):
    r, g, b = pixel[0] & 255, pixel[1] & 255, pixel[2] & 255
    r, g, b = r >> 3, g >> 2, b >> 3
    return (r << 11) | (g << 5 ) | b


im = Image.open(sys.argv[1]).convert('RGB')
if im.size != (240,320):
    print ("image not 240x320-- exiting")
    sys.exit(1)


cols = {}
print ("Analysizing image...")

for i in range(0,76800):
    x = i % 240
    y = i // 240
    c = RGB(im.getpixel((x,y)))

    if not c in cols: cols[c] = [i]
    else: cols[c].append(i)


(longcol, longlen) = (0, 0)
for k in cols.keys():
    d = len(cols[k])
    if d > longlen:
        longcol = k
        longlen = d
print ("majority colour={0} ({1} occurrences)".format(longcol,longlen))
tosend = []
cols.pop(longcol)


print ("RLE Compressing image...")
for k in cols.keys():

    addr = '*{:04X}'.format(k)
    s = ""
    p = cols[k]

    while len(p) != 0:
        sp = p[0]
        l = 0
        while len(p) > 1 and p[0]+1 == p[1]:
            l += 1
            p = p[1:]

        s += '{:<9X}'.format((320*240*l)+sp)
        p = p[1:]

    t = ""
    while len(s) > 0:
        (a, s) = re.split(' +', s, 1)
        t += a + " "
        if len(t) > ORGMAXLEN or (len(s) == 0 and len(t) > 0):
            tosend.append(addr + t)
            t = ""

print ("Unwrapped line count:", len(tosend))
print ("Sortings colors...")

resend = []
for k in sorted(tosend, key=coloursort): resend.append(k)
tosend = [ '\r*{:04X} 15F900000'.format(longcol) ] + resend


print ("Transmitting image over the network...")

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((UNOIP, 6666))
time.sleep(1)
p = 0
maxlen = 1

while len(tosend):
    d = ""
    while len(d) < maxlen and len(tosend) > 0:
        d += tosend[0] + '\r'
        tosend = tosend[1:]

    print ('\r', len(tosend), end='')
    sys.stdout.flush()

    totalsent = 0
    while totalsent < len(d):
        sent = s.send(bytes(d[totalsent:], encoding='utf-8'))
        if sent == 0: raise RuntimeError("socket connection broken")
        totalsent = totalsent + sent
    time.sleep (0.0085 + (len(d)/11500.0))
    #time.sleep(1)
    if p < 2: time.sleep(0.5)
    else: maxlen = 200
    p = p + 1

print ("Actual packets send:",p)
s.close()

